from PyQt5.uic import loadUi
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QSlider,QComboBox,QCheckBox,QApplication, QMainWindow, QGraphicsScene, QGraphicsView
from CvCamThread import CameraThread
from drawroi import GraphicsViewDrawer
import configparser
import cv2
import sys
import traceback

def excepthook(exc_type, exc_value, exc_tb):
    traceback.print_exception(exc_type, exc_value, exc_tb)
    sys.exit(1)

sys.excepthook = excepthook  # 重写异常钩子


class MainWindow(QtWidgets.QMainWindow):
    params = {
        "FRAME_HEIGHT": cv2.CAP_PROP_FRAME_HEIGHT,
        "FPS": cv2.CAP_PROP_FPS,
        "BRIGHTNESS": cv2.CAP_PROP_BRIGHTNESS,
        "CONTRAST": cv2.CAP_PROP_CONTRAST,
        "SATURATION": cv2.CAP_PROP_SATURATION,
        "HUE": cv2.CAP_PROP_HUE,
        "GAIN": cv2.CAP_PROP_GAIN,
        "EXPOSURE": cv2.CAP_PROP_EXPOSURE,
        "AUTO_EXPOSURE": cv2.CAP_PROP_AUTO_EXPOSURE,
        "AUTOFOCUS": cv2.CAP_PROP_AUTOFOCUS,
        "WB_TEMPERATURE": cv2.CAP_PROP_WB_TEMPERATURE,
        "AUTO_WB": cv2.CAP_PROP_AUTO_WB,
        "BACKLIGHT": cv2.CAP_PROP_BACKLIGHT,
        "SHARPNESS": cv2.CAP_PROP_SHARPNESS,
        "GAMMA": cv2.CAP_PROP_GAMMA,
        }
    
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        loadUi('main.ui', self)

        self.drawer1=GraphicsViewDrawer(self.graphicsView)

        #建立画板
        self.drawer1.graphics_view.draw=""
        self.drawer1.graphics_view.flag=False
        
        self.camera_thread = None  # 初始化摄像头线程
        
        #定义槽函数
        #self.saveButton.clicked.connect(self.save_setting)
        self.camera_thread = CameraThread(0)
        self.camera_thread.change_pixmap.connect(self.update_image)
        #摄像头初始化完成后再载入设置
        self.camera_thread.cap_initialized.connect(self.load_config)
        self.camera_thread.start()
        
        self.RectangleRoi.triggered.connect(self.set_rectangle_mode)  # 使用 triggered 信号
        self.EllipseRoi.triggered.connect(self.set_ellipse_mode)  # 使用 triggered 信号
        self.action_photo.triggered.connect(self.photo)#拍照
        self.action_record.triggered.connect(self.record)#录像
        self.action_crop.triggered.connect(self.crop) #ROI区域截图保存
            
 

    #枚举摄像头
    def load_config(self, cam_id):
        config = configparser.ConfigParser()
        try:
            config.read("seting.ini", encoding="utf-8")
            print(f"读取配置文件成功")
        except Exception as e:
            print(f"读取配置文件失败: {e}")
            return

        # 动态匹配摄像头配置（例如 Camera1）
        section_name = f"Camera{cam_id}"
        if not config.has_section(section_name):
            print(f"配置文件中缺少 {section_name} 段落！")
            return

        # 初始化摄像头
        #self.cap = self.camera_thread.cap
        if not self.camera_thread.cap.isOpened():
            print(f"摄像头 {cam_id} 无法打开！")
            return

        # 遍历配置项并设置参数
        for param_name in config[section_name]:
            #configparser 默认会将键名转为小写
            if param_name.upper() in self.params:
                param_id = self.params[param_name.upper()]
                value = config[section_name].getint(param_name)
                success = self.camera_thread.set_param(param_id, value)
                if success:
                    print(f"{param_name} = {value}（成功）")
                else:
                    print(f"警告：{param_name} 不支持当前摄像头")



    def update_image(self, q_img):
        pixmap = QPixmap.fromImage(q_img)
        
        # 更安全的场景清理方式
        current_items = self.drawer1.scene.items()
        for item in current_items:
            # 仅删除图像项，保留ROI图形
            if isinstance(item, QtWidgets.QGraphicsPixmapItem):
                self.drawer1.scene.removeItem(item)
        
        # 添加新图像项并设置层级
        item = QtWidgets.QGraphicsPixmapItem(pixmap)
        item.setZValue(0)  # 图像在底层
        self.drawer1.scene.addItem(item)
        
        # 初始化ROI加载（仅首次）
        if not hasattr(self, 'roi_loaded'):
            self.drawer1.pixmap_item = item  # 传递图片引用
            self.drawer1.load_roi()
            self.roi_loaded = True
        
        # 视图适配
        self.drawer1.graphics_view.fitInView(item, Qt.KeepAspectRatio)
        self.drawer1.graphics_view.centerOn(item)
        
        

    def set_rectangle_mode(self):
        if self.RectangleRoi.isChecked():
            self.drawer1.draw_mode = "Rect"  
            self.EllipseRoi.setChecked(False)  # 禁用椭圆模式
        else:
            self.drawer1.draw_mode = ""  


    def set_ellipse_mode(self):
        if self.EllipseRoi.isChecked():
            self.drawer1.draw_mode = "Ellipse"  # 设置为椭圆模式
            self.RectangleRoi.setChecked(False)  # 禁用矩形模式
        else:
            self.drawer1.draw_mode = ""

    def photo(self):
        self.camera_thread.capture()

    def record(self):
        if self.action_record.isChecked():
            self.camera_thread.record_start(fps=30)
        else:
            self.camera_thread.record_stop()
        
    def crop(self):
        x=self.drawer1.roi_x
        y=self.drawer1.roi_y
        width=self.drawer1.roi_width
        height=self.drawer1.roi_height
        self.camera_thread.crop_rect(x, y, width, height)
        


if __name__ == "__main__":
    # 创建了一个PyQt封装的QApplication对象,创建的时候,把系统参数传进去了.顾名思义,这一句创建了一个应用程序对象
    app = QtWidgets.QApplication(sys.argv)
    # #创建一个我们生成的那个窗口，注意把类名修改为MainWindow
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())
